﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MatchBilingualSent
{
    class SimilarlySentenceClassifier
    {
        WordSeg.WordSeg wordSeg;
        WordSeg.Tokens tokens;

        public void Initialize(WordSeg.WordSeg w)
        {
            wordSeg = w;
            tokens = wordSeg.CreateTokens(1000);
        }

        public bool FirstTermMatch(List<BiToken> engTokenList, List<BiToken> chiTokenList)
        {
            if (engTokenList.Count == 0 || chiTokenList.Count == 0)
            {
                return false;
            }

            BiToken token = null;
            for (int i = 0; i < engTokenList.Count; i++)
            {
                if (is_mark(engTokenList[i].strTerm) == false)
                {
                    token = engTokenList[i];
                    break;
                }
            }
            if (token != null)
            {
                foreach (BiToken item in chiTokenList)
                {
                    if (token.strTerm == item.strTerm)
                    {
                        return true;
                    }

                    foreach (string strExplain in item.strExplainList)
                    {
                        if (token.strTerm == strExplain)
                        {
                            return true;
                        }
                    }
                }
            }

            token = null;
            for (int i = 0; i < chiTokenList.Count; i++)
            {
                if (is_mark(chiTokenList[i].strTerm) == false)
                {
                    token = chiTokenList[i];
                    break;
                }
            }
            if (token != null)
            {
                foreach (BiToken item in engTokenList)
                {
                    if (token.strTerm == item.strTerm)
                    {
                        return true;
                    }

                    foreach (string strExplain in item.strExplainList)
                    {
                        if (token.strTerm == strExplain)
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }


        public bool LastTermMatch(List<BiToken> engTokenList, List<BiToken> chiTokenList)
        {
            if (engTokenList.Count == 0 || chiTokenList.Count == 0)
            {
                return false;
            }

            BiToken token = null;
            for (int i = engTokenList.Count - 1; i >= 0; i--)
            {
                if (is_mark(engTokenList[i].strTerm) == false)
                {
                    token = engTokenList[i];
                    break;
                }
            }
            if (token != null)
            {
                foreach (BiToken item in chiTokenList)
                {
                    if (token.strTerm == item.strTerm)
                    {
                        return true;
                    }

                    foreach (string strExplain in item.strExplainList)
                    {
                        if (token.strTerm == strExplain)
                        {
                            return true;
                        }
                    }
                }
            }

            token = null;
            for (int i = chiTokenList.Count - 1; i >= 0; i--)
            {
                if (is_mark(chiTokenList[i].strTerm) == false)
                {
                    token = chiTokenList[i];
                    break;
                }
            }
            if (token != null)
            {
                foreach (BiToken item in engTokenList)
                {
                    if (token.strTerm == item.strTerm)
                    {
                        return true;
                    }

                    foreach (string strExplain in item.strExplainList)
                    {
                        if (token.strTerm == strExplain)
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        private bool is_mark(char c)
        {
            return (c == ' ' || c == '.' || c == ',' || c == '!' || c == '?' || c == '\"' || c == '\'' || c == '-' || c == ':');
        }

        private bool is_mark(string s)
        {
            for (int i = 0; i < (int)s.Length; i++)
            {
                if (!is_mark(s[i]))
                {
                    return false;
                }
            }
            return true;
        }

        public double SimilarlySentence(List<BiToken> engTokenList, List<BiToken> chiTokenList)
        {
            double fMatchedTermCoverageRate;
            bool bFirstTermMatched, bLastTermMatched;
            fMatchedTermCoverageRate = GetMatchedTermCoverage(engTokenList, chiTokenList);
            bFirstTermMatched = FirstTermMatch(engTokenList, chiTokenList);
            bLastTermMatched = LastTermMatch(engTokenList, chiTokenList);

            double score = 0.0;
            if (bFirstTermMatched == true)
            {
                score += 0.01;
            }
            if (bLastTermMatched == true)
            {
                score += 0.01;
            }

            score += fMatchedTermCoverageRate * 0.98;

            return score;
        }


        private double GetMatchedTermCoverage(List<BiToken> engTokenList, List<BiToken> chiTokenList)
        {
            if (engTokenList.Count == 0 || chiTokenList.Count == 0)
            {
                return 0.0;
            }

            bool[] engMatchBitList;
            bool[] chiMatchBitList;

            engMatchBitList = new bool[engTokenList.Count];
            chiMatchBitList = new bool[chiTokenList.Count];


            for (int i = 0; i < engTokenList.Count; i++)
            {
                bool hasEngMatch = false;
                for (int j = 0;j < chiTokenList.Count;j++)
                {
                    if (engTokenList[i].strTerm == chiTokenList[j].strTerm)
                    {
                        hasEngMatch = true;
                        engMatchBitList[i] = true;
                        chiMatchBitList[j] = true;
                    }
                }
                if (hasEngMatch == false)
                {
                    foreach (string strExplain in engTokenList[i].strExplainList)
                    {
                        for (int j = 0;j < chiTokenList.Count;j++)
                        {
                            if (strExplain == chiTokenList[j].strTerm && is_mark(strExplain) == false)
                            {
                                engMatchBitList[i] = true;
                                chiMatchBitList[j] = true;
                            }
                        }
                    }
                }
            }

            double nMatchCntE = 0.0;
            double nMatchCntC = 0.0;
            foreach (bool flag in engMatchBitList)
            {
                if (flag == true)
                {
                    nMatchCntE++;
                }
            }

            foreach (bool flag in chiMatchBitList)
            {
                if (flag == true)
                {
                    nMatchCntC++;
                }
            }

            return (double)nMatchCntC / (double)chiMatchBitList.Length * (double)nMatchCntE / (double)engMatchBitList.Length;
        }
    }
}
